package com.jike.jkgame.widget.slidemenu;

import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicBoolean;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.jike.jkgame.R;

public class SlideBarMenu extends FrameLayout {

	private static final int DEFAULT_ITEM_SPACING = 10;
	private static final boolean DEFAULT_CLOSE_ON_CLICK = true;
	private static final int DEFAULT_EXPAND_DURATION = 1000;
	
	private static final int[] MENU_ITEM_IDS = {R.id.iv_menu_home, R.id.iv_menu_shop, R.id.iv_menu_treasure,
		R.id.iv_menu_strengthen, R.id.iv_menu_attack, R.id.iv_menu_lineup, R.id.iv_menu_mission};

	private Animation mainRotateRight;
	private Animation mainRotateLeft;
	private Animation barOut;
	private Animation barIn;

	private ImageView imgMain;
	private MenuItemClickedListener itemClickedListener;

	// private List<SlideMenuItem> menuItems = new ArrayList<SlideMenuItem>();
	// private Map<View, SlideMenuItem> viewToItemMap = new HashMap<View,
	// SlideMenuItem>();

	private AtomicBoolean plusAnimationActive = new AtomicBoolean(false);

	// States of these variables are saved
	private boolean rotated = false;
	private int measureDiff = 0;
	// States of these variables are saved - Also configured from XML
	private int itemSpacing = DEFAULT_ITEM_SPACING;
	private int expandDuration = DEFAULT_EXPAND_DURATION;
	private boolean closeItemsOnClick = DEFAULT_CLOSE_ON_CLICK;
	private View barView;

	private Handler mHandler = new Handler();

	public SlideBarMenu(Context context) {
		super(context);
		init(context, null, 0);
	}

	public SlideBarMenu(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs, 0);
	}

	public SlideBarMenu(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context, attrs, defStyle);
	}

	private void init(Context context, AttributeSet attrs, int defStyle) {
		LayoutInflater.from(context).inflate(R.layout.slidebar_menu_layout,
				this, true);
		imgMain = (ImageView) findViewById(R.id.iv_menu_main);
		barView = findViewById(R.id.menu_bar);

		mainRotateLeft = SlideAnimationCreator
				.createMainButtonAnimation(context);
		mainRotateRight = SlideAnimationCreator
				.createMainButtonInverseAnimation(context);

		barOut = SlideAnimationCreator.createMenuBarOutAnimation(context);
		barIn = SlideAnimationCreator.createMenuBarInAnimation(context);
		
		Animation.AnimationListener plusAnimationListener = new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				plusAnimationActive.set(false);
			}
		};
		
		Animation.AnimationListener slideAnimationListener = new AnimationListener() {
			
			@Override
			public void onAnimationStart(Animation animation) {
				if (!rotated) {
					barView.setVisibility(View.VISIBLE);
				}
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {
				
			}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				if (rotated) {
					barView.setVisibility(View.GONE);
				}
			}
		};

		mainRotateLeft.setAnimationListener(plusAnimationListener);
		mainRotateRight.setAnimationListener(plusAnimationListener);
		
		barOut.setAnimationListener(slideAnimationListener);
		barIn.setAnimationListener(slideAnimationListener);
		
		imgMain.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				SlideBarMenu.this.onClick();
			}
		});

		// 把item进行关联
		for (int i = 0; i < MENU_ITEM_IDS.length; ++i) {
			View item = findViewById(MENU_ITEM_IDS[i]);
			initMenuItem(item, i);
		}
	}
	
	private void initMenuItem(View v, int id) {
		final Animation anim = SlideAnimationCreator.createItemClickAnimation(getContext());
		anim.setAnimationListener(new MenuItemClickAnimationListener(this, id));
		v.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				v.startAnimation(anim);
			}
		});
	}

	private void onClick() {
		if (plusAnimationActive.compareAndSet(false, true)) {
			if (!rotated) {
				imgMain.startAnimation(mainRotateLeft);
				// for (SlideMenuItem item : menuItems) {
				// item.getView().startAnimation(item.getOutAnimation());
				// }
				barView.startAnimation(barOut);
			} else {
				imgMain.startAnimation(mainRotateRight);
				// for (SlideMenuItem item : menuItems) {
				// item.getView().startAnimation(item.getInAnimation());
				// }
				barView.startAnimation(barIn);
			}
			rotated = !rotated;
		}
	}

	private void openItems() {
		if (plusAnimationActive.compareAndSet(false, true)) {
			if (!rotated) {
				imgMain.startAnimation(mainRotateLeft);
				// for (SlideMenuItem item : menuItems) {
				// item.getView().startAnimation(item.getOutAnimation());
				// }
				barView.startAnimation(barOut);
			}
			rotated = !rotated;
		}
	}

	private void closeItems() {
		if (plusAnimationActive.compareAndSet(false, true)) {
			if (rotated) {
				imgMain.startAnimation(mainRotateRight);
				// for (SlideMenuItem item : menuItems) {
				// item.getView().startAnimation(item.getInAnimation());
				// }
				barView.startAnimation(barIn);
			}
			rotated = !rotated;
		}
	}

	private void resetItems() {
		// if (menuItems.size() > 0) {
		// List<SlideMenuItem> items = new ArrayList<SlideMenuItem>(
		// menuItems);
		// menuItems.clear();
		// this.removeAllViews();
		// addItems(items);
		// }
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		// recalculateMeasureDiff();
		//
		// int totalHeight = imgMain.getHeight();
		// int totalWidth = imgMain.getWidth() + measureDiff * menuItems.size();
		// setMeasuredDimension(totalWidth, totalHeight);
	}
	
	private static class MenuItemClickAnimationListener implements
			Animation.AnimationListener {
		private WeakReference<SlideBarMenu> menuRef;
		private int tag;

		public MenuItemClickAnimationListener(SlideBarMenu menu, int tag) {
			this.menuRef = new WeakReference<SlideBarMenu>(menu);
			this.tag = tag;
		}

		@Override
		public void onAnimationEnd(Animation animation) {
		}

		@Override
		public void onAnimationRepeat(Animation animation) {
		}

		@Override
		public void onAnimationStart(Animation animation) {
			SlideBarMenu menu = menuRef.get();
			if (menu != null && menu.closeItemsOnClick) {
				// menu.close();
				if (menu.itemClickedListener != null) {
					menu.itemClickedListener.eventOccured(tag);
				}
			}
		}
	}

	private static FrameLayout.LayoutParams getLayoutParams(View view) {
		return (FrameLayout.LayoutParams) view.getLayoutParams();
	}

	/**
	 * Sets the click listener for satellite items.
	 * 
	 * @param itemClickedListener
	 */
	public void setOnItemClickedListener(
			MenuItemClickedListener listner) {
		this.itemClickedListener = listner;
	}

	/**
	 * Defines the total space between the initial and final item in degrees.
	 * Note: Calling before adding items is strongly recommended.
	 * 
	 * @param totalSpacingDegree
	 *            The degree between initial and final items.
	 */
	public void setItemSpacing(int spacing) {
		this.itemSpacing = spacing;
		// resetItems();
	}

	/**
	 * Sets the duration for expanding and collapsing the items in miliseconds.
	 * Note: Calling before adding items is strongly recommended.
	 * 
	 * @param expandDuration
	 *            the duration for expanding and collapsing the items in
	 *            miliseconds.
	 */
	public void setExpandDuration(int expandDuration) {
		this.expandDuration = expandDuration;
		// resetItems();
	}

	/**
	 * Sets the image resource for the center button.
	 * 
	 * @param resource
	 *            The image resource.
	 */
	public void setMainImage(int resource) {
		this.imgMain.setImageResource(resource);
	}

	/**
	 * Sets the image drawable for the center button.
	 * 
	 * @param resource
	 *            The image drawable.
	 */
	public void setMainImage(Drawable drawable) {
		this.imgMain.setImageDrawable(drawable);
	}

	/**
	 * Defines if the menu shall collapse the items when an item is clicked.
	 * Default value is true.
	 * 
	 * @param closeItemsOnClick
	 */
	public void setCloseItemsOnClick(boolean closeItemsOnClick) {
		this.closeItemsOnClick = closeItemsOnClick;
	}

	/**
	 * The listener class for item click event.
	 * 
	 * @author Siyamed SINIR
	 */
	public interface MenuItemClickedListener {
		/**
		 * When an item is clicked, informs with the id of the item, which is
		 * given while adding the items.
		 * 
		 * @param id
		 *            The id of the item.
		 */
		public void eventOccured(int id);
	}

	/**
	 * Expand the menu items.
	 */
	public void expand() {
		openItems();
	}

	/**
	 * Collapse the menu items
	 */
	public void close() {
		closeItems();
	}

}
